#include "config.h"

#include "ms2sim.h"

ecm_uint32	n_medias;
ecm_uint32	max_media_length;

static ecm_uint64	n_total_requested;
static ecm_ptrs_t	*ptrs_media;

static void
free_media(media_t *media)
{
	if (media == NULL)
		return;
	msl_iastat_free(media->iastat);
	ecm_free(media->name);
	ecm_free(media);
}

static ECMBOOL
do_add_media(sr_t *sr_media)
{
	media_t	*media;

	media = (media_t *)ecm_malloc(sizeof(media_t));
	if (media == NULL) {
		ERR("media: out of memory");
		return ECM_FALSE;
	}

	media->iastat = msl_iastat_create();
	media->name = ecm_strdup(sr_getc_str(sr_media, "name"));
	media->length = msl_parse_duration((char *)sr_getc_str(sr_media, "length"));
	if (media->length == 0) {
		ERR("media %s: invalid length", ecm_safe_str(media->name));
		free_media(media);
		return ECM_FALSE;
	}
	media->mid = n_medias + 1;
	media->n_requested = 0;

	//TODO only CBR ?? VBR needed.
	if (!msl_parse_bandwidth((char *)sr_getc_str(sr_media, "CBR"), &media->bitrate)) {
		ERR("media %s: invalid bit rate", ecm_safe_str(media->name));
		free_media(media);
		return ECM_FALSE;
	}

	media->size = media->length * media->bitrate;

	media->bid_max = media->size / cache_blksize + 1;

	ecm_ptrs_add(ptrs_media, media);

	n_medias++;

	return ECM_TRUE;
}

ECMBOOL
add_media(sr_t *sr_media)
{
	ecm_uint32	count, i;

	count = sr_getc_int(sr_media, "count");
	if (count == 0)
		count = 1;
	for (i = 0; i < count; i++) {
		sr_t	*sr_media_my = sr_dup(sr_media);
		if (!do_add_media(sr_media_my)) {
			sr_free(sr_media_my);
			return ECM_FALSE;
		}
		sr_free(sr_media_my);
	}
	return ECM_TRUE;
}

media_t *
access_media(ecm_uint64 ts, ecm_uint32 mid)
{
	media_t	*media;

	media = ecm_ptrs_get(ptrs_media, mid);
	ECMASSERT(media != NULL);

	media->n_requested++;
	n_total_requested++;

	msl_iastat_add(media->iastat, ts / 1000000);

	return media;
}

media_t *
get_media(ecm_uint32 mid)
{
	return (media_t *)ecm_ptrs_get(ptrs_media, mid);
}

ecm_uint32
get_media_iablks(ecm_uint32 mid)
{
	media_t	*media;
	ecm_uint32	iatime;

	media = ecm_ptrs_get(ptrs_media, mid);
	ECMASSERT(media != NULL);

	iatime = msl_iastat_get(media->iastat);
	if (iatime == 0)
		return 0;
	return (media->bitrate * iatime) / disk_blksize;
}

void
check_media_stats(void)
{
}

void
report_media_result(void)
{
	media_t	*media;
	int	i;

	printlog("Number of Medias:            %u\n", n_medias);
	printlog("Number of Media Requested:   %I64u\n", n_total_requested);
	printlog("# Media Detailed Information:\n");
	printlog("# Media    Popularity    Size     BitRate    Avg Interarrival time\n");
	for (i = 1; i <= n_medias; i++) {
		char	*media_size_str, *bitrate_str;

		media = ecm_ptrs_get(ptrs_media, i);

		media_size_str = ecm_strdup(msl_get_capacity_str(media->size));
		bitrate_str = ecm_strdup(msl_get_bandwidth_str(media->bitrate));
		printlog("[%4u]:  %6.2lf%%       %s   %s      %s\n", i, 100.0 * media->n_requested / n_total_requested,
			 media_size_str, bitrate_str,
			 msl_get_duration_str(msl_iastat_get(media->iastat)));
		ecm_free(media_size_str);
		ecm_free(bitrate_str);
	}
}

ECMBOOL
init_media_pre(void)
{
	ptrs_media = ecm_ptrs_new(16);

	return ECM_TRUE;
}

ECMBOOL
init_media(void)
{
	media_t		*media;
	ecm_uint32	i;

	for (i = 0; i < ptrs_media->count; i++) {
		media = (media_t *)ptrs_media->pdata[i];
		bcache_op->add_media(media->bid_max);
		if (media->length > max_media_length)
			max_media_length = media->length;
	}

	return ECM_TRUE;
}
